//
//  main.m
//  RECoMMand
//
//  Created by Zhiqiang Bao on 15-1-16.
//  Copyright (c) 2015年 Zhiqiang Bao. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "commutils.h"
#include "shell_processor.h"
#include <arpa/inet.h>
#import "NSTaskProcessor.h"

#define BUFFERLEN   4096

#define VERSION     "0.0.1"

void show_help_information () {
    printf("Version %s version, use:\n", VERSION);
    printf("     recommand ip port  --- connect the one need help\n");
    printf("     recommand port     --- wait for someone else to connect you\n\n");
    printf("A sample:\n");
    printf("     recommand 127.0.0.1 8787\n\n");
}

void wait_for_help (const char *port) {
    printf("waiting for someone else to help...\n\n");
    int fd = tcp_server(atoi(port));
    if (fd != -1) {
        struct sockaddr_in clientaddr;
        int socketaddrLen = sizeof(struct sockaddr_in);
        int retFd = ::accept(fd, (struct sockaddr *)&clientaddr, (socklen_t*)&socketaddrLen);
        if (retFd != -1) {
            printf("%s(%d) has connected!\n\n", inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port);
            printf("**************** remote control begin ****************\n\n");
            
            char buf[BUFFERLEN + 1];
            char output[BUFFERLEN + 1], *ptr = output;
            
            NSTaskProcessor *processor = [[NSTaskProcessor alloc] init];
            [processor.readPipe.fileHandleForReading setReadabilityHandler:^(NSFileHandle *handle) {
                
                NSData *data = handle.availableData;
                [data getBytes:ptr length:BUFFERLEN];
                ptr[data.length] = '\0';
                
                // 输出结果
                printf("%s\n", ptr);
                fd_send_msg(retFd, ptr, (int)data.length);
                
            }];
            
            printf(">");
            while (true) {
                // 接收完一条命令
                int len = fd_recv_msg(retFd, buf, BUFFERLEN);
                
                if (len == 0) continue;
                
                buf[len] = '\0';
                printf("%s", buf);
                
                // 处理
                [processor processCommand:buf];
                
                // sleep 100 ms for result
                usleep(100000);
                
                printf(">");
            }
            
            return;
        }
    }
    
    printf("start up failed!\n\n");
}

void connect_to_help (const char *ip, const char *port) {
    printf("connecting to %s:(%s)...\n\n", ip, port);
    int fd = tcp_client(ip, atoi(port));
    if (fd != -1) {
        printf("you have connected to %s(%s)!\n\n", ip, port);
        printf("**************** remote control begin ****************\n\n");
        
        char buf[BUFFERLEN + 1];
        char output[BUFFERLEN + 1], *ptr = output;
        
        NSFileHandle *handle = [[NSFileHandle alloc] initWithFileDescriptor:fd closeOnDealloc:YES];
        
        [handle setReadabilityHandler:^(NSFileHandle *handle) {
            
            int len = fd_recv_msg(handle.fileDescriptor, ptr, BUFFERLEN);
            ptr[len] = '\0';
            
            // 输出结果
            printf("%s\n", ptr);
        }];
        
        printf(">");
        while (true) {
            buf[0] = '\0';
            
            // 获取输入
            fgets(buf, BUFFERLEN, stdin);
            
            if (strlen(buf) == 0) continue;
            
            fd_send_msg(fd, buf, (int)strlen(buf));
            
            // sleep 100 ms for result
            usleep(100000);
            
            printf(">");
        }
        
        
    }else{
        printf("connect failed!\n\n");
    }
}

int main(int argc, const char * argv[]) {
    if (argc == 2) {
        wait_for_help(argv[1]);
    } else if (argc == 3) {
        connect_to_help(argv[1], argv[2]);
    } else {
        show_help_information();
    }
    
    return 0;
}
